Fortran For Fun之进度显示

在fortran输出advence = ‘no’的情况下,输出前面加上achar(13)可以删除原来的输出,在同一行重新进行输出,以下字符为

1
2
3
4
achar(8) !< 退格符
achar(9) !< 制表符
achar(10) !< 换行符
achar(13) !< 回车符

overwrite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
program learn_overwrite
use iso_c_binding
implicit none
integer :: i
integer, parameter :: n = 100
interface
subroutine wait(usec) bind(C,name='usleep')
use iso_c_binding
integer(c_int),value::usec
end subroutine wait
end interface
do i = 1, n
write(*,'(a,f6.2,a)',advance='no') char(13),real(i),'%'
call wait(50000)
enddo
write(*,*)
end program learn_overwrite

结果

会动态显示 1% ~ 100%

show_progress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
program learn_show_progress
use iso_c_binding
implicit none
interface
subroutine wait(usec) bind(C,name='usleep')
use iso_c_binding
integer(c_int),value::usec
end subroutine wait
end interface
integer :: n
write(*, *) 'initialize progress'
do n = 1,100
call wait(100000)
call show_progress(n/100.0)
enddo
write(*,*)
contains
subroutine show_progress(p)
real,intent(in)::p
!! Progress fraction \(p\in[0,1]\), 0 = start progress 1 = complete progress
integer :: i
integer :: n = 60
real ::r
character(3) :: persent
write(persent,'(i0)') int(p*100)
write(*,'(a)',advance='no') achar(13)//' ['
do i=1,60
r = real(i-1)/real(N-1)
if(r<=p) then
write(*,'(1a)',advance='no') '='
else
write(*,'(1a)',advance='no') ' '
endif
end do
write(*,'(a)',advance='no') '] '//trim(persent)//' %'
! flush(*)
end subroutine show_progress
end program learn_show_progress

结果

动态显示整个过程

1
2
initialize progress
[============================================================] 100 %

结合之前的颜色模块可以使输出带有颜色,输出更加友好。